﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DaliUsbDemo.DaliHelper.MemoryBank
{
  internal static class ControlGearMemoryBank
  {
    private static List<string> cgMemoryBank0LocationDescriptions = new List<string>()
        {
            "last accesible memory location",
            "reserved",
            "last accesible memory bank",
            "GTIN byte 0",
            "GTIN byte 1",
            "GTIN byte 2",
            "GTIN byte 3",
            "GTIN byte 4",
            "GTIN byte 5",
            "firmware version (major)",
            "firmware version (minor)",
            "identification number byte 0",
            "identification number byte 1",
            "identification number byte 2",
            "identification number byte 3",
            "identification number byte 4",
            "identification number byte 5",
            "identification number byte 6",
            "identification number byte 7",
            "hardware version (major)",
            "hardware version (minor)",
            "101 version number",
            "102 version number",
            "103 version number",
            "number of logical control devices",
            "number of logical control gears",
            "index of logical control gear",
            "current bus unit configuration" // new defined in diiasw098bg
        };

    private static List<string> cgMemoryBank1LocationDescriptions = new List<string>()
    {
        "last accessible memory location",
        "indicator byte",
        "memory bank 1 lock byte",
        "OEM GTIN byte 0",
        "OEM GTIN byte 1",
        "OEM GTIN byte 2",
        "OEM GTIN byte 3",
        "OEM GTIN byte 4",
        "OEM GTIN byte 5",
        "OEM identification number byte 0",
        "OEM identification number byte 1",
        "OEM identification number byte 2",
        "OEM identification number byte 3",
        "OEM identification number byte 4",
        "OEM identification number byte 5",
        "OEM identification number byte 6",
        "OEM identification number byte 7",
        "Content Format ID (MSB)", // D4i Part 251 extension ...
        "Content Format ID (LSB)",
        "Luminaire year of manufacturer [YY]",
        "Luminaire year of manufacturer [WW]",
        "Nominal Input Power [W] (MSB)",
        "Nominal Input Power [W] (LSB)",
        "Power at min dim level [W] (MSB)",
        "Power at min dim level [W] (LSB)",
        "Nominal Min AC mains Voltage [V] (MSB)",
        "Nominal Min AC mains Voltage [V] (LSB)",
        "Nominal Max AC mains Voltage [V] (MSB)",
        "Nominal Max AC mains Voltage [V] (LSB)",
        "Nominal light output [Lm] (MSB)",
        "Nominal light output [Lm] Byte1",
        "Nominal light output [Lm] (LSB)",
        "CRI",
        "CCT[K] (MSB)",
        "CCT[K] (LSB)",
        "Light Distribution Type",
        //"Luminaire color [24 ASCII char string] (0)",
        // "Luminaire ID [60 ASCII char string] (1)",
    };

    private static List<string> cgMemoryBank136LocationDescriptions = new List<string>()
    {
      "last accessible memory location",
      "indicator byte",
      "memory bank 136 lock byte",
      /*"version of the memory bank", */
      "DA_RX 1TE Low Avg [1/16Mhz] (LSB)",
      "DA_RX 1TE Low Avg [1/16Mhz] (MSB)",
      "DA_RX 1TE Low Max [1/16Mhz] (LSB)",
      "DA_RX 1TE Low Max [1/16Mhz] (MSB)",
      "DA_RX 1TE Low Min [1/16Mhz] (LSB)",
      "DA_RX 1TE Low Min [1/16Mhz] (MSB)",
      "DA_RX 1TE High Avg [1/16Mhz] (LSB)",
      "DA_RX 1TE High Avg [1/16Mhz] (MSB)",
      "DA_RX 1TE High Max [1/16Mhz] (LSB)",
      "DA_RX 1TE High Max [1/16Mhz] (MSB)",
      "DA_RX 1TE High Min [1/16Mhz] (LSB)",
      "DA_RX 1TE High Min [1/16Mhz] (MSB)",
      "DA_RX 2TE Low Avg [1/16Mhz] (LSB)",
      "DA_RX 2TE Low Avg [1/16Mhz] (MSB)",
      "DA_RX 2TE Low Max [1/16Mhz] (LSB)",
      "DA_RX 2TE Low Max [1/16Mhz] (MSB)",
      "DA_RX 2TE Low Min [1/16Mhz] (LSB)",
      "DA_RX 2TE Low Min [1/16Mhz] (MSB)",
      "DA_RX 2TE High Avg [1/16Mhz] (LSB)",
      "DA_RX 2TE High Avg [1/16Mhz] (MSB)",
      "DA_RX 2TE High Max [1/16Mhz] (LSB)",
      "DA_RX 2TE High Max [1/16Mhz] (MSB)",
      "DA_RX 2TE High Min [1/16Mhz] (LSB)",
      "DA_RX 2TE High Min [1/16Mhz] (MSB)",
      "DA RX InterEdgeInvlid Counter (LSB)",
      "DA RX InterEdgeInvlid Counter (1)",
      "DA RX InterEdgeInvlid Counter (2)",
      "DA RX InterEdgeInvlid Counter (MSB)",
      "DA RX Falling CalibOffset [1/16Mhz] (LSB)",
      "DA RX Falling CalibOffset [1/16Mhz] (MSB)",
      "DA RX Rising CalibOffset [1/16Mhz] (LSB)",
      "DA RX Rising CalibOffset [1/16Mhz] (MSB)",
      "DA TX Falling CalibOffset [1/16Mhz] (LSB)",
      "DA TX Falling CalibOffset [1/16Mhz] (MSB)",
      "DA TX Rising CalibOffset [1/16Mhz] (LSB)",
      "DA TX Rising CalibOffset [1/16Mhz] (MSB)",
      "MCU Temperature (LSB)",
      "MCU Temperature (MSB)",
      "User Var 0 (LSB)",
      "User Var 0 (MSB)",
      "User Var 1 (LSB)",
      "User Var 1 (MSB)",
      "User Var 2 (LSB)",
      "User Var 2 (MSB)",
      "User Var 3 (LSB)",
      "User Var 3 (MSB)",
    };

    private static List<string> cgMemoryBank202LocationDescriptions = new List<string>()
    {
      "last accessible memory location",
      "indicator byte",
      "memory bank 202 lock byte",
      "version of the memory bank",
      "ScaleFactorForActiveEnergy",
      "ActiveEnergy (MSB)",
      "ActiveEnergy (Byte4)",
      "ActiveEnergy (Byte3)",
      "ActiveEnergy (Byte2)",
      "ActiveEnergy (Byte1)",
      "ActiveEnergy (LSB)",
      "ScaleFactorForActivePower",
      "ActivePower (MSB)",
      "ActivePower (Byte2)",
      "ActivePower (Byte1)",
      "ActivePower (LSB)",
    };

    private static List<string> cgMemoryBank203LocationDescriptions = new List<string>()
    {
      "last accessible memory location",
      "indicator byte",
      "memory bank 203 lock byte",
      "version of the memory bank",
      "ScaleFactorForApparentEnergy",
      "ApparentEnergy (MSB)",
      "ApparentEnergy (Byte4)",
      "ApparentEnergy (Byte3)",
      "ApparentEnergy (Byte2)",
      "ApparentEnergy (Byte1)",
      "ApparentEnergy (LSB)",
      "ScaleFactorForApparentPower",
      "ApparentPower (MSB)",
      "ApparentPower (Byte2)",
      "ApparentPower (Byte1)",
      "ApparentPower (LSB)",
    };
    private static List<string> cgMemoryBank204LocationDescriptions = new List<string>()
    {
      "last accessible memory location",
      "indicator byte",
      "memory bank 204 lock byte",
      "version of the memory bank",
      "ScaleFactorForLoadsideEnergy",
      "ActiveEnergyLoadside (MSB)",
      "ActiveEnergyLoadside (Byte4)",
      "ActiveEnergyLoadside (Byte3)",
      "ActiveEnergyLoadside (Byte2)",
      "ActiveEnergyLoadside (Byte1)",
      "ActiveEnergyLoadside (LSB)",
      "ScaleFactorForLoadsidePower",
      "ActivePowerLoadside (MSB)",
      "ActivePowerLoadside (Byte2)",
      "ActivePowerLoadside (Byte1)",
      "ActivePowerLoadside (LSB)",
    };

    private static List<string> cgMemoryBank205LocationDescriptions = new List<string>()
    {
      "last accessible memory location",
      "indicator byte",
      "memory bank 205 lock byte",
      "version of the memory bank",
      "ControlGearOperatingTime (MSB)",
      "ControlGearOperatingTime (Byte2)",
      "ControlGearOperatingTime (Byte1)",
      "ControlGearOperatingTime (LSB)",
      "ControlGearStartCounter (MSB)",
      "ControlGearStartCounter (Byte1)",
      "ControlGearStartCounter (LSB)",
      "ControlGearExternalSupplyVoltage (MSB)",
      "ControlGearExternalSupplyVoltage (LSB)",
      "ControlGearExternalSupplyVoltageFrequency",
      "ControlGearPowerFactor",
      "ControlGearOverallFailureCondition",
      "ControlGearOverallFailureConditionCounter",
      "ControlGearExternalSupplyUndervoltage",
      "ControlGearExternalSupplyUndervoltageCounter",
      "ControlGearExternalSupplyOvervoltage",
      "ControlGearExternalSupplyOvervoltageCounter",
      "ControlGearOutputPowerLimitation",
      "ControlGearOutputPowerLimitationCounter",
      "ControlGearThermalDerating",
      "ControlGearThermalDeratingCounter",
      "ControlGearThermalShutdown",
      "ControlGearThermalShutdownCounter",
      "ControlGearTemperature",
      "ControlGearOutputCurrentPercent" /* 0x1C / 28 */
    };


    private static List<string> cgMemoryBank206LocationDescriptions = new List<string>()
    {
      "last accessible memory location",
      "indicator byte",
      "memory bank 206 lock byte",
      "version of the memory bank",
      "LightSourceStartCounterResettable (MSB)",
      "LightSourceStartCounterResettable",
      "LightSourceStartCounterResettable (LSB)",
      "LightSourceStartCounter (MSB)",
      "LightSourceStartCounter",
      "LightSourceStartCounter (LSB)",
      "LightSourceOnTimeResettable (MSB)",
      "LightSourceOnTimeResettable",
      "LightSourceOnTimeResettable",
      "LightSourceOnTimeResettable (LSB)",
      "LightSourceOnTime (MSB)",
      "LightSourceOnTime",
      "LightSourceOnTime",
      "LightSourceOnTime (LSB)",
      "LightSourceVoltage (MSB)",
      "LightSourceVoltage (LSB)",
      "LightSourceCurrent (MSB)",
      "LightSourceCurrent (LSB)",
      "LightSourceOverallFailureCondition",
      "LightSourceOverallFailureConditionCounter",
      "LightSourceShortCircuit",
      "LightSourceShortCircuitCounter",
      "LightSourceOpenCircuit",
      "LightSourceOpenCircuitCounter",
      "LightSourceThermalDerating",
      "LightSourceThermalDeratingCounter",
      "LightSourceThermalShutdown",
      "LightSourceThermalShutdownCounter",
      "LightSourceTemperature", /* 0x20 / 30 */
    };

    private static List<string> cgMemoryBank207LocationDescriptions = new List<string>()
    {
      "last accessible memory location",
      "indicator byte",
      "memory bank 207 lock byte",
      "version of the memory bank",
      "RatedMedianUsefulLifeOfLuminaire",
      "InternalControlGearReferenceTemperature",
      "RatedMedianUsefulLightSourceStarts (MSB)",
      "RatedMedianUsefulLightSourceStarts (LSB)", /* 0x07 / 7 */
    };


    public static string GetLocationDescription(int bank, int location)
    {
      if ((bank < 0) || (bank > 255) || (location < 0) || (location > 255))
      {
        throw new ArgumentOutOfRangeException("bank or location value is not valid!");
      }

      switch (bank)
      {
        case 0:
          return (location < cgMemoryBank0LocationDescriptions.Count) ? cgMemoryBank0LocationDescriptions[location] : "";
        case 1:
          if ((location >= 0x24) && (location <= 0x3B)) /* [0x24, 0x3B] : Luminaire color [24 ASCII char string] */
          {
            return String.Format("Luminaire color [24 ASCII char string] ({0})", location - 0x24);
          }
          else if ((location >= 0x3C) && (location <= 0x77))  /* [0x3C, 0x77] : Luminaire ID [60 ASCII char string] */
          {
            return String.Format("Luminaire ID [60 ASCII char string] ({0})", location - 0x3C);
          }
          else
          {
            return (location < cgMemoryBank1LocationDescriptions.Count) ? cgMemoryBank1LocationDescriptions[location] : "";
          }
        case 136:
          return (location < cgMemoryBank136LocationDescriptions.Count) ? cgMemoryBank136LocationDescriptions[location] : "";
        case 202:
          return (location < cgMemoryBank202LocationDescriptions.Count) ? cgMemoryBank202LocationDescriptions[location] : "";
        case 203:
          return (location < cgMemoryBank203LocationDescriptions.Count) ? cgMemoryBank203LocationDescriptions[location] : "";
        case 204:
          return (location < cgMemoryBank204LocationDescriptions.Count) ? cgMemoryBank204LocationDescriptions[location] : "";
        case 205:
          return (location < cgMemoryBank205LocationDescriptions.Count) ? cgMemoryBank205LocationDescriptions[location] : "";
        case 206:
          return (location < cgMemoryBank206LocationDescriptions.Count) ? cgMemoryBank206LocationDescriptions[location] : "";
        case 207:
          return (location < cgMemoryBank207LocationDescriptions.Count) ? cgMemoryBank207LocationDescriptions[location] : "";
        default:
          return "";
      }
    }
  }
}
